/*
* INSANE - Interactive Structural Analysis Environment
*
* Copyright (C) 2003-2004
* Universidade Federal de Minas Gerais
* Escola de Engenharia
* Departamento de Engenharia de Estruturas
*
* Author's email : insane@dees.ufmg.br
* Author's Website : http://www.dees.ufmg.br/insane
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
package br.ufmg.dees.insane.model.xfemModel.xfemElement;

import java.util.ArrayList;
import java.util.List;

import br.ufmg.dees.insane.materialMedia.degeneration.Degeneration;
import br.ufmg.dees.insane.materialMedia.degeneration.PrescribedDegeneration;
import br.ufmg.dees.insane.materialMedia.degeneration.Representation;
import br.ufmg.dees.insane.materialMedia.degeneration.Thickness;
import br.ufmg.dees.insane.materialMedia.materialPoint.MaterialPoint;
import br.ufmg.dees.insane.model.xfemModel.enrichmentItem.EnrichmentItem;
import br.ufmg.dees.insane.util.IMatrix;
import br.ufmg.dees.insane.util.INaturalCoords;
import br.ufmg.dees.insane.util.IPoint3d;
import br.ufmg.dees.insane.util.IVector;
import br.ufmg.dees.insane.util.extrapolation.TriangularLagrangeanExtrapolation2D;
import br.ufmg.dees.insane.util.numericalIntegration.AreaGaussPoint;
import br.ufmg.dees.insane.util.numericalIntegration.IntegrationPoint;

/**
 * @author Kelson Wolff
 *
 */
public abstract class XFEMTriangular extends XFEMElement {
	
	/**
	 * Comment for <code>serialVersionUID</code>
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * 
	 */
	public XFEMTriangular() {
		super();
		// TODO Auto-generated constructor stub
	}
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.element.ParametricElement#initDegenerations()
	 */
	@Override
	public void initDegenerations()
    {
		int k = 1;
		IntegrationPoint ip = new AreaGaussPoint();
		for(int i = 0; i < (this.integrationOrder.getXiIntegOrder()); i++)
		{
			Representation representation = new Representation();
			INaturalCoords nc = new INaturalCoords();
			nc.setCsi1(ip.getCoord(this.integrationOrder.getXiIntegOrder()-1,(3*i)));
			nc.setCsi2(ip.getCoord(this.integrationOrder.getXiIntegOrder()-1,(3*i+1)));
			representation.setNaturalcoords(nc);
			representation.setWeight(ip.getWeight(this.integrationOrder.getXiIntegOrder()-1,i));
			representation.setAnalysisModel(this.getAnalysisModel());
			representation.setCm(this.getConstitutiveModel());
			((Degeneration)this.getDegenerations().get(k-1)).setRepresentation(representation);
			((Degeneration)this.getDegenerations().get(k-1)).setLabel("IP-"+k);
			k++;
		}
    }

	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.element.ParametricElement#getElmCoefficient()
	 */
	@Override
	/** Return the element integrationCoefficient
	*@return The thickness * 1/2 of this triangular parametric element.
	*/
	public double getElmCoefficient()
	{
		return 0.5;
	}

	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.element.ParametricElement#addDegeneration(br.ufmg.dees.insane.materialMedia.degeneration.Degeneration)
	 */
	@Override
	public void addDegeneration(Degeneration dg){
		if (dg instanceof PrescribedDegeneration) {
		    try {
			this.degenerations.add((PrescribedDegeneration)(((PrescribedDegeneration)dg).clone()));
		    }
		    catch (CloneNotSupportedException e) {
			e.printStackTrace();
		    }
		}
		else {
		    Degeneration dgn = new Thickness();
		    dgn.setOriginalLabel(dg.getOriginalLabel());

		    for(int i = 0; i<dg.getMaterialPoints().size(); i++){
		    	try {
		    		((Degeneration)dgn).add((MaterialPoint)(dg.getMaterialPoint(i)).clone());
		    	}
		    	catch (CloneNotSupportedException e) {
		    		e.printStackTrace();
		    	}
		    }
		    this.degenerations.add(dgn);
		}
	}
	
	public void addDegenerations(List<Degeneration> dgs){
		this.degenerations.addAll(dgs);
	}

	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.xfemModel.element.XFEMElement#getMyArea()
	 */
	@Override
	public abstract double getMyArea(); 
	
	/**
	 * Gets the number of faces of this Element.
	 * @return Returns the number of faces of this Element.
	 */
	public abstract int getNbFaces();
	
	/**
	 * Gets the number of nodes pertaining at each face of this Element.
	 * @return Returns the number of nodes pertaining at each face of this Element.
	 */
	public abstract int getNbNodesFace();
	
	/**
	 * Gets the Incidence List (Nodes List) of this Element setted in a counter-clock-wise order.
	 * @return Returns the incidence List of this Element setted in a counter-clock-wise order.
	 */
	public abstract ArrayList getCCWIncidence();
	
	/**
	 * Gets the Incidence Array (Nodes Array)of this Element that hold the label of each node
	 * getted in a counter-clock-wise order.
	 * @return Returns the Incidence Array of this Element that hold the label of each node
	 * getted in a counter-clock-wise order.
	 */
	public abstract String[] getCCWIncidenceString();
	
	/**
	 * Sets the Incidence List (Nodes List) of this Element in a 
	 * counter-clock-wise order.
	 */
	public abstract void setCCWIncidence();
	
	@Override
	public IVector extrapolatesToNodes(ArrayList natCoords, ArrayList value) {
		TriangularLagrangeanExtrapolation2D extra = new TriangularLagrangeanExtrapolation2D(natCoords,value);
		IMatrix nodeNatCoords = this.Shape.getNaturalNodalCoords();
		IVector values = new IVector(nodeNatCoords.getNumCol());
		for (int i = 0; i < nodeNatCoords.getNumCol(); i++) {
		    IPoint3d p = new IPoint3d(nodeNatCoords.getElement(0,i),nodeNatCoords.getElement(1,i));
		    values.setElement(i,extra.extrapolateTo(p));
		}
		return values;
	}

	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.xfemModel.xfemElement.XFEMElement#setEnrichmentForMyNodes(br.ufmg.dees.insane.model.xfemModel.enrichmentItem.EnrichmentItem)
	 */
	@Override
	public void setEnrichmentForMyNodes(EnrichmentItem enrItem) {
		// TODO Auto-generated method stub
		
	}

}
